using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Collections;

namespace Sinacor.Infra.UI.Controls.SmartClient
{
    internal class SinacorDragAdorner : Adorner
    {
        protected UIElement _child;
        protected double XCenter;
        protected double YCenter;

        double _leftOffset;
        double _topOffset;

        public double LeftOffset
        {
            get { return _leftOffset; }
            set
            {
                _leftOffset = value - XCenter;
                UpdatePosition();
            }
        }
        public double TopOffset
        {
            get { return _topOffset; }
            set
            {
                _topOffset = value - YCenter;

                UpdatePosition();
            }
        }
        protected override int VisualChildrenCount
        {
            get
            {
                return 1;
            }
        }

        public SinacorDragAdorner(UIElement adornedElement, IDragSource dragSource)
            : base(adornedElement)
        {
            _child = this.GetRectangle((FrameworkElement)dragSource);
        }

        public SinacorDragAdorner(UIElement adornedElement, ItemsControl itemsControl, IEnumerable items)
            : base(adornedElement)
        {
            StackPanel internalStack = new StackPanel();

            foreach (object item in items)
            {
                FrameworkElement fe;

                if (!(item is FrameworkElement))
                    fe = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement;
                else
                    fe = (FrameworkElement)item;

                if (fe != null)
                    internalStack.Children.Add(this.GetRectangle(fe));
            }

            _child = internalStack;
        }

        protected Rectangle GetRectangle(FrameworkElement item)
        {
            FrameworkElement adornerContent = ((IDragSource)item).GetDraggedContent();

            VisualBrush brush = new VisualBrush(adornerContent);
            brush.Opacity = 0.5;
            Rectangle r = new Rectangle();

            r.Width = adornerContent.ActualWidth;
            r.Height = adornerContent.ActualHeight;

            XCenter = adornerContent.DesiredSize.Width / 2;
            YCenter = adornerContent.DesiredSize.Height / 2;

            r.Fill = brush;

            return r;
        }

        public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
        {
            GeneralTransformGroup result = new GeneralTransformGroup();
            result.Children.Add(base.GetDesiredTransform(transform));
            result.Children.Add(new TranslateTransform(_leftOffset, _topOffset));
            return result;
        }

        void UpdatePosition()
        {
            AdornerLayer adorner = (AdornerLayer)this.Parent;
            if (adorner != null)
            {
                adorner.Update(this.AdornedElement);
            }
        }

        protected override Visual GetVisualChild(int index)
        {
            return _child;
        }

        protected override Size MeasureOverride(Size finalSize)
        {
            _child.Measure(finalSize);
            return _child.DesiredSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            _child.Arrange(new Rect(_child.DesiredSize));
            return finalSize;
        }
    }
}